package com.software.audiorecorddemo

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.util.Log
import androidx.core.content.ContextCompat
import java.io.File
import java.io.FileOutputStream
import java.io.IOException

/**
 * 音频采集类
 * 负责管理AudioRecord的创建、启动、停止和释放
 * 通过回调机制将采集到的音频数据传递给上层
 */
class AudioCapture(
    private val context: Context,
    private val callback: AudioCaptureCallback,
    private val sampleRate: Int = 44100,
    private val channels: Int = 1,
    private val audioFormat: Int = AudioFormat.ENCODING_PCM_16BIT
) {
    companion object {
        private const val TAG = "AudioCapture"
    }

    // 音频采集器
    private var audioRecord: AudioRecord? = null
    
    // 缓冲区大小
    private val bufferSize: Int
    
    // 录音线程
    private var recordingThread: Thread? = null
    
    // 是否正在录制
    private var isRecording = false
    
    init {
        // 根据通道数获取通道配置
        val channelConfig = if (channels == 1) {
            AudioFormat.CHANNEL_IN_MONO
        } else {
            AudioFormat.CHANNEL_IN_STEREO
        }
        
        // 获取缓冲区大小
        bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat)
        
        if (bufferSize <= 0) {
            Log.e(TAG, "无效的AudioRecord参数配置，bufferSize = $bufferSize")
        }
    }
    
    /**
     * 初始化AudioRecord
     */
    @SuppressLint("MissingPermission")
    private fun initAudioRecord(): Boolean {
        // 检查权限
        if (ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.RECORD_AUDIO
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            Log.e(TAG, "缺少RECORD_AUDIO权限")
            callback.onError("缺少录音权限")
            return false
        }
        
        try {
            // 获取通道配置
            val channelConfig = if (channels == 1) {
                AudioFormat.CHANNEL_IN_MONO
            } else {
                AudioFormat.CHANNEL_IN_STEREO
            }
            
            // 创建AudioRecord实例
            audioRecord = AudioRecord(
                MediaRecorder.AudioSource.MIC,
                sampleRate,
                channelConfig,
                audioFormat,
                bufferSize
            )
            
            // 检查是否初始化成功
            if (audioRecord?.state != AudioRecord.STATE_INITIALIZED) {
                Log.e(TAG, "AudioRecord初始化失败，状态: ${audioRecord?.state}")
                callback.onError("AudioRecord初始化失败")
                releaseAudioRecord()
                return false
            }
            
            return true
        } catch (e: SecurityException) {
            Log.e(TAG, "安全异常: ${e.message}")
            callback.onError("安全异常: ${e.message}")
        } catch (e: Exception) {
            Log.e(TAG, "初始化AudioRecord失败: ${e.message}")
            callback.onError("初始化AudioRecord失败: ${e.message}")
        }
        
        return false
    }
    
    /**
     * 开始录音
     */
    fun startRecording(): Boolean {
        // 如果已经在录制，返回错误
        if (isRecording) {
            Log.d(TAG, "已经在录音中")
            return false
        }
        
        // 初始化AudioRecord
        if (!initAudioRecord()) {
            return false
        }
        
        try {
            // 开始录制
            audioRecord?.startRecording()
            
            // 检查录制状态
            if (audioRecord?.recordingState != AudioRecord.RECORDSTATE_RECORDING) {
                Log.e(TAG, "开始录音失败")
                callback.onError("开始录音失败")
                releaseAudioRecord()
                return false
            }
            
            isRecording = true
            callback.onRecordingStarted()
            
            // 创建录音线程
            recordingThread = Thread(RecordingRunnable())
            recordingThread?.start()
            
            return true
        } catch (e: IllegalStateException) {
            Log.e(TAG, "开始录音失败: ${e.message}")
            callback.onError("开始录音失败: ${e.message}")
            releaseAudioRecord()
        } catch (e: Exception) {
            Log.e(TAG, "录音过程发生错误: ${e.message}")
            callback.onError("录音过程发生错误: ${e.message}")
            releaseAudioRecord()
        }
        
        return false
    }
    
    /**
     * 停止录音
     */
    fun stopRecording() {
        // 如果没有在录制，直接返回
        if (!isRecording) {
            return
        }
        
        // 设置录制状态，使录音线程退出循环
        isRecording = false
        
        try {
            // 等待录音线程结束
            recordingThread?.join(2000)
            recordingThread = null
            
            // 停止AudioRecord
            audioRecord?.stop()
            releaseAudioRecord()
            
            callback.onRecordingStopped()
        } catch (e: Exception) {
            Log.e(TAG, "停止录音失败: ${e.message}")
            callback.onError("停止录音失败: ${e.message}")
        }
    }
    
    /**
     * 释放AudioRecord资源
     */
    private fun releaseAudioRecord() {
        try {
            audioRecord?.release()
            audioRecord = null
        } catch (e: Exception) {
            Log.e(TAG, "释放AudioRecord失败: ${e.message}")
        }
    }
    
    /**
     * 录音线程
     */
    private inner class RecordingRunnable : Runnable {
        override fun run() {
            // 创建数据缓冲区
            val buffer = ByteArray(bufferSize)
            
            while (isRecording) {
                // 读取音频数据
                val readSize = audioRecord?.read(buffer, 0, buffer.size) ?: -1
                
                // 检查读取结果
                if (readSize > 0) {
                    // 通过回调将数据传给上层
                    callback.onAudioDataAvailable(buffer.copyOf(readSize))
                } else if (readSize == AudioRecord.ERROR_INVALID_OPERATION) {
                    Log.e(TAG, "读取音频数据失败: 无效操作")
                    break
                } else if (readSize == AudioRecord.ERROR_BAD_VALUE) {
                    Log.e(TAG, "读取音频数据失败: 参数错误")
                    break
                }
            }
            
            Log.d(TAG, "录音线程结束")
        }
    }

    /**
     * 获取当前采样率
     */
    fun getSampleRate(): Int = sampleRate
    
    /**
     * 获取当前通道数
     */
    fun getChannels(): Int = channels
    
    /**
     * 获取当前音频格式
     */
    fun getAudioFormat(): Int = audioFormat
    
    /**
     * 获取缓冲区大小
     */
    fun getBufferSize(): Int = bufferSize
    
    /**
     * 音频采集回调接口
     */
    interface AudioCaptureCallback {
        /**
         * 当音频数据可用时回调
         */
        fun onAudioDataAvailable(data: ByteArray)
        
        /**
         * 录音开始时回调
         */
        fun onRecordingStarted()
        
        /**
         * 录音停止时回调
         */
        fun onRecordingStopped()
        
        /**
         * 发生错误时回调
         */
        fun onError(error: String)
    }
} 